// This is a conversation I had with a friend of mine, Disch. He is a // well known ROM hacker, and I thought this conversation we had could // help others understand how the Stack Pointer and Program Counter // work. [23:39] *** Now talking to Disch [23:39] Disch is ~disch_@dpc67143199073.direcpc.com Disch [23:39] Disch on @#rom-hacking @#rom-hacking-ops [23:39] Disch using discworld.esper.net Fabricati deim, pvnc. [23:39] Disch has identified for this nick [23:39] Disch, I am having issues with the Stack Pointer and Program Counter [23:40] I know you're not 24/7 encyclopedia, but I need some help here... [23:40] How do they work? [23:40] What do they do? [23:40] The Program Counter just tells where the CPU is executing from [23:40] like if the PC is at $8000 ... then the next instruction to be executed comes from $8000 [23:41] JMP $C123 <--- all that does is set the PC to $C123 ... so that it's the next instruction executed [23:41] The Stack Pointer just tells where the top of the stack is [23:41] What is the stack? [23:41] okay [23:41] imagine a stack of plates [23:42] or [23:42] before it's a stack [23:42] say I just put one plate on the table [23:42] and another plate on top of it [23:42] the second plate is now the top of the stack... and in order to take off any plates below it, I need to take off that top plate first [23:43] it's kind of hard to explain... [23:43] but okay [23:43] you know about PHA and PLA? [23:43] I haven't began to delve into ALL the mnemonics yet [23:43] I only know maybe 10 offhand at most [23:43] well I can run through them [23:43] Maybe 20 [23:44] PHA "pushes" a value onto the stack (like adding another plate to the stack) [23:44] Onto the top? [23:44] PLA "pulls" a value off the stack (like taking a plate off) [23:44] so here's an example: [23:44] LDA #$00 ; stack: empty [23:45] PHA ; stack: [top] $00 [bottom] [23:45] LDA #$65 [23:45] PHA ; stack: [top] $65 $00 [bottom] [23:45] LDA #$23 [23:45] PHA ; stack: [top] $23 $65 $00 [bottom] [23:46] LDA #$00 [23:46] PLA ; A is now $23, stack: [top] $65 $00 [bottom] [23:46] PLA ; A is now $65 stack: [top] $00 [bottom] [23:46] make sense? [23:47] Yeah, but whats the deal with the second $00? [23:47] I get the rest, by the way [23:47] just to show that PLA changes A [23:48] Oh [23:48] so anyway [23:48] the stack exists on the $01xx page [23:48] where the Stack Pointer (SP) determines the next place to be the top of the stack [23:48] $100 - $1FF? [23:48] yeah [23:49] now the stack is actually backwards kinda [23:49] $01FF is the normal "bottom" of the stack [23:49] so when the stack is empty... SP is $FF [23:49] when a value is pushed... it gets written to $0100+SP then SP is decremented [23:50] when a value is pulled, SP gets incremented... then the value returned is from $0100+SP [23:50] am I making sense? lol [23:50] Yeah, it made sense when I remembered to read "$01FF is the bottom" [23:51] Until then, I was kinda confused [23:51] heh [23:51] so any more Q's? ^^ [23:52] So when we push from $FF, incrementing by $01, we are now at $FE? [23:52] that's decrementing.. no incrementing ;P but yeah that's right [23:53] LDA #$00 ; if SP is $FF here... [23:53] Ah, decrementing [23:53] PHA ; $00 gets written to $01FF here, SP is now $FE [23:53] But we're pushing [23:53] And pulling brings it back to FF [23:53] right [23:53] Sweet [23:53] Now what can that do for a game? [23:53] well [23:53] Pushing and Pulling? [23:53] the stack is mostly used with JSR/RTS [23:54] Bit shifts? [23:54] JSR is like JMP... only it "saves" the PC by pushing it to the stack [23:54] RTS pulls that back from the stack [23:54] so like [23:54] say a game has a subroutine to print some text [23:55] at address $C654 [23:55] $C654: [23:55] LDA blah [23:55] STA blah [23:55] ; more crap to print text [23:55] RTS [23:55] then elsewhere in the game [23:55] say you want to print some text... move the player... then print some more text [23:56] say you're at $8000 or something [23:56] $8000: [23:56] JSR $C654 ; jump to draw text routine [23:56] ; when the draw text routine hits that RTS, execution will continue from here [23:56] JSR Move_player [23:56] JSR $C654 [23:56] ; to print more text [23:57] make sense? [23:57] I didn't know Move_player was a valid syntax...I always thought it was Hex numbers after a Mnemonic [23:58] well that was just an example [23:58] (if you're using an assembler you can use labels and stuff -- but whatever) [23:58] put a number there for Move_player then ;P [23:59] Lol [23:59] hmmm... [00:00] So JSR jumps right to C654> [00:00] ?* [00:00] yeah [00:00] but [00:00] it also pushes the return address ($8003) to the stack [00:00] Ahhh [00:00] so when the game hits RTS.. it'll pull the address from the stack and jump to it [00:01] "I'm gonna jump to C654 now, but first I'm gonna make sure the the of the Stack is set to where I am now first" [00:01] Right? [00:01] actually... technically it would push $8002 ;P [00:01] yeah [00:01] Aight :) [00:01] RTS is "go back to wherever called JSR last" [00:01] Ahh :) [00:02] "Now I've visited C654 and done my business, now lets go back to where the top of the Stack tells us to"? [00:02] yep [00:02] :D [00:03] This convo should be placed on Romhacking.net :p [00:03] haw [00:03] "Understanding the Stack Pointer" [00:03] feel free to submit it or whatever